package org.jianfa.learn.oss.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import org.apache.commons.lang3.StringUtils;
import org.jianfa.learn.oss.config.AliyunConfig;
import org.jianfa.learn.oss.service.StorageService;
import org.jianfa.learn.oss.vo.HttpResponse;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.UUID;

@Service
public class AliyunStorageServiceImpl implements StorageService {

    private final AliyunConfig aliyunConfig;
    private OSS ossClient;

    // 允许上传的格式
    private static final String[] IMAGE_TYPE = new String[]{".jpg", ".jpeg", ".png"};

    @Autowired
    public AliyunStorageServiceImpl(AliyunConfig aliyunConfig) {
        this.aliyunConfig = aliyunConfig;
    }

    @PostConstruct
    public void postConstruct() {
        // 创建OSSClient实例。
        ossClient = new OSSClientBuilder().build(aliyunConfig.getEndpoint(),
                                                 aliyunConfig.getAccessKeyId(),
                                                 aliyunConfig.getAccessKeySecret());
    }

    @PreDestroy
    public void preDestroy() {
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * upload
     *
     * @param multipartFile
     * @return
     */
    public HttpResponse upload(MultipartFile multipartFile) {
        // 校验图片格式
        boolean  isLegal = false;
        for (String type:IMAGE_TYPE){
            if(StringUtils.endsWithIgnoreCase(multipartFile.getOriginalFilename(),type)){
                isLegal = true;
                break;
            }
        }

        if (!isLegal){
            return new HttpResponse.Builder().status("error").message("{\"msg\":\"不支持的格式!\"}").build();
        }

        String fileName = multipartFile.getOriginalFilename();
        String filePath = getFilePath(fileName);
        try {
            // <yourObjectName>表示上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
            PutObjectRequest putObjectRequest = new PutObjectRequest(aliyunConfig.getBucketName(), filePath, new ByteArrayInputStream(multipartFile.getBytes()));

            //  上传文件
            ossClient.putObject(putObjectRequest);
        } catch (IOException e) {
            e.printStackTrace();
            // 上传失败
            return  new HttpResponse.Builder().status("error").message("{\"msg\":\"上传失败\"}").build();
        }

        return  new HttpResponse.Builder().status("done").message("{\"msg\":\"上传成功\",\"fileName\":\"" +  filePath + "\"}").build();
    }

    /**
     * download
     *
     * @param filename
     * @return
     */
    public Resource download(String filename) {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        String objectName = "lagou/" + filename;
        OSSObject ossObject = ossClient.getObject(aliyunConfig.getBucketName(), objectName);

        InputStreamResource inputStreamResource = new InputStreamResource(ossObject.getObjectContent());
        return inputStreamResource;
    }

    /**
     * delete
     *
     * @param filename
     * @return
     */
    public HttpResponse delete(String filename) {
        // 删除文件。如需删除文件夹，请将ObjectName设置为对应的文件夹名称。如果文件夹非空，则需要将文件夹下的所有object删除后才能删除该文件夹。
        String objectName = "lagou/" + filename;
        ossClient.deleteObject(aliyunConfig.getBucketName(), objectName);

        return new HttpResponse.Builder().status("done").message("{\"msg\":\"上传成功\"}").build();
    }

    // 生成不重复的文件路径和文件名
    private String getFilePath(String sourceFileName) {
        DateTime dateTime = new DateTime();
        return "lagou/" + dateTime.toString("yyyy")
                + "/" + dateTime.toString("MM") + "/"
                + dateTime.toString("dd") + "/" + UUID.randomUUID().toString() + "." +
                StringUtils.substringAfterLast(sourceFileName, ".");
    }


}
